﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;

//---------------------------------------------------------------------------------//

//--------------------------------AGA关联规则产生算法------------------------------//

//---------------------------------------------------------------------------------//


namespace LJTest
{
    class RalationRule
    {
        public ArrayList rules;
        public ArrayList frequency;
        public ArrayList frequency_no;
         ArrayList Lc;
         ArrayList Lsub;
        public RalationRule()
        {
           // readRules();
           
            readFrequency(); 
            readTransaction();
        }
        /* **
         * 读取关联规则文件
         * 
         ** */
      
        public void readRules()
        {
            if (File.Exists(Common.RULE_FILE_PATH))
            {
                try
                {
                    String InLine;
                    ArrayList total = new ArrayList();
                    ArrayList sub = new ArrayList();
                   
                    using (StreamReader sr = new StreamReader(Common.RULE_FILE_PATH, Encoding.GetEncoding("gb2312")))
                    {
                        while ((InLine = sr.ReadLine()) != null)
                        {
                            int firstIndex = InLine.IndexOf("->");
                            if (firstIndex == 0)
                            {
                                sub.Add(InLine.Substring(2, InLine.Length - 2)); //确定只有一个数字，没有逗号

                            }
                            else
                            {
                                sub.Add(InLine.Substring(0, firstIndex)); //箭头前面的一个数字
                                string str = InLine.Substring(firstIndex + 2, InLine.Length - 2 - firstIndex);
                                foreach (string k in str.Split(','))
                                {
                                    sub.Add(k);
                                }
                            }
                           
                            total.Add(sub);
                            sub = new ArrayList();
                        }
                    }
                 
                    rules = total;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("读取关联规则中的记录出错：" + ex.Message);

                }
            }

        }
        

        /* **
         * 读取频繁项集
         * 
         ** */
        public void readFrequency()
        {
            if (File.Exists(Common.FREQUENCY_FILE_PATH))
            {
                try
                {
                    String InLine;
                    frequency = new ArrayList();
                    frequency_no = new ArrayList();
                    ArrayList sub = new ArrayList();

                    using (StreamReader sr = new StreamReader(Common.FREQUENCY_FILE_PATH, Encoding.GetEncoding("gb2312")))
                    {
                        while ((InLine = sr.ReadLine()) != null)
                        {
                            //Console.WriteLine(InLine);
                            if (InLine != null && !InLine.Equals(""))
                            {
                                int firstIndex = InLine.IndexOf("|");

                                frequency_no.Add(InLine.Substring(0, firstIndex)); //箭头前面的一个数字
                                string str = InLine.Substring(firstIndex + 1, InLine.Length - 1 - firstIndex);
                                foreach (string k in str.Split(','))
                                {
                                    sub.Add(k);
                                }

                                frequency.Add(sub);
                                sub = new ArrayList();
                            }

                        }
                    }
                   

                }
                catch (Exception ex)
                {
                    Console.WriteLine("读取频繁项集中的记录出错：" + ex.Message);
                }
            }
        }

        /* **
         * 生成关联规则
         * 
         ** */
        public  ArrayList AGArules(double mf)
        {
            Console.WriteLine("生成关联规则开始");
            ArrayList rules=new ArrayList ();
            ArrayList I = new ArrayList();
            ArrayList Ino = new ArrayList();
            int num = 0;
            int n = 0;
            int k=Lc.Count/2;
           
                foreach (ArrayList fre in frequency)
                {

                    if (fre.Count == 1)
                    {
                        I.Add(fre[0]);
                        Ino.Add(frequency_no[n]);
                        int nn=Convert.ToInt32(frequency_no[n]); 
                       double kk = Convert.ToDouble(nn)/Convert.ToDouble(k);
                       //double y = Convert.ToDouble( 5 )/ Convert.ToDouble( 4 );
                        if (kk>= mf)
                        {
                            rules.Add(kk+ "|->" + fre[0]);
                            //写入缓存中：

                            string sql = "insert into cache values('" + DateTime.Now.ToString("s") + "' ,'" + DateTime.Now.ToString("s") + "','" + fre[0] + "','" + Common.CaculateDataSize(fre[0].ToString()) + "','" + "N" + "')";
                            SQLiteHelper.ExecuteSql(sql);
                        }

                    }
                    else
                    {
                        foreach (string l in fre)
                        {
                            //Console.WriteLine("I.Contains(" + l + ")=" + I.Contains(l));
                            double x = calculate(Convert.ToInt32(frequency_no[n]), I, Ino, l);
                            if (I.Contains(l) && ( x >= Convert.ToDouble(mf)))
                            {
                                string str = "";
                                int sindex = 0;
                                foreach (string s in fre)
                                {
                                    str += (s.Equals(l) ? "" : s+",");
                                   
                                }
                                str = str.Substring(0, str.Length - 1);
                                rules.Add(x+"|"+l + "->" + str);
                                //I.Remove(l);
                            }
                        }

                    }

                    n++;
                                 
                  
                }
                StreamWriter transtreamwriter = new StreamWriter(Common.RULE_FILE_PATH, true);
                foreach (string str in rules)
                {
                    transtreamwriter.WriteLine(str);
                }
                transtreamwriter.Close();
                Console.WriteLine("生成关联规则结束，结果已写入文件");
                return rules;
            
        }

        public static bool isContains(ArrayList arraylist, string s)
        {
            foreach (string str in arraylist)
            {
                if (str.Equals(s)) return true;
            }
            return false;
        }

        public static double calculate(int support, ArrayList fi,ArrayList fi_no , string item)
        {
            double x;
            int index = 0;
            foreach(string str in fi)
            {
                if(str.Equals(item))
                {
                       break; 
                }else
                {
                    index++;
                }
            }
           x = Convert.ToDouble( support / Convert.ToDouble(fi_no[index]));
            // x = Convert.ToDecimal( Convert.ToInt32(fi_no[index]) /support);
            //Console.WriteLine("x=" + x);
            return x;
           


        }


        public void readTransaction()
        {
          //读事务
            //Console.WriteLine("读事务开始");
            if (File.Exists(Common.TRANSACTION_FILE_PATH))
            {
                Console.WriteLine("文件查找成功");
                try
                {
                    String InLine;
                    Lc = new ArrayList();
                    Lsub = new ArrayList();

                    using (StreamReader sr = new StreamReader(Common.TRANSACTION_FILE_PATH, Encoding.GetEncoding("gb2312")))
                    {


                        while ((InLine = sr.ReadLine()) != null)
                        {
                            foreach (string k in InLine.Split(','))
                            {
                                Lsub.Add(k);
                            }
                            Lc.Add(Lsub);
                            Lsub = new ArrayList();
                        }
                    }
                }

                catch (Exception ex)
                {
                    Console.WriteLine("文件操作失败" + ex.Message);

                }
            }
            else
            {
                Console.WriteLine("文件查找失败");
            }
           // Console.WriteLine("读事务结束");
        }


    }

    
}
